/**
 @file ctc_packet.h

 @author  Copyright (C) 2012 Centec Networks Inc.  All rights reserved.

 @date 2012-11-25

 @version v2.0

   This file contains all packet related data structure, enum, macro and proto.
*/

#ifndef _CTC_PACKET_H
#define _CTC_PACKET_H

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_const.h"
#include "ctc_chip.h"

/****************************************************************
*
* Defines and Macros
*
****************************************************************/
/**
 @defgroup packet PACKET
 @{
*/

/**
 @brief Define packet related MACROs
*/
#define CTC_PKT_HDR_ROOM    64                          /**< [GB.GG] Header room length in bytes */
#define CTC_PKT_MTU         (9600 + CTC_PKT_HDR_ROOM)   /**< [GB.GG] Max packet length in bytes, include header room */

/**
 @brief Define packet transport mode
*/
enum ctc_pkt_mode_e
{
    CTC_PKT_MODE_DMA,           /**< [GB.GG] Packet is transported by DMA */
    CTC_PKT_MODE_ETH            /**< [GB.GG] Packet is transported by Ethernet */
};
typedef enum ctc_pkt_mode_e ctc_pkt_mode_t;

/**
 @brief Define packet RX/TX flag
*/
enum ctc_pkt_flag_e
{
    CTC_PKT_FLAG_MCAST              = 0x0001,  /**< [GB.GG] [RX,TX] Is multicast packet or not */
    CTC_PKT_FLAG_SRC_SVID_VALID     = 0x0002,  /**< [GB.GG] [RX,TX] Source svlan id is set */
    CTC_PKT_FLAG_SRC_CVID_VALID     = 0x0004,  /**< [GB.GG] [RX,TX] Source cvlan id is set */
    CTC_PKT_FLAG_PRIORITY           = 0x0008,  /**< [GB.GG] [RX,TX] Priority is set */
    CTC_PKT_FLAG_COLOR              = 0x0010,  /**< [GB.GG] [RX,TX] Color is set */
    CTC_PKT_FLAG_NH_OFFSET_BYPASS   = 0x0020,  /**< [GB.GG] [TX] Use bypass NH offset, higher than NH_OFFSET_VALID */
    CTC_PKT_FLAG_NH_OFFSET_VALID    = 0x0040,  /**< [GB[GG]] [TX] Use field nh_offset, otherwise use bridge NH offset, lower than NH_OFFSET_BYPASS */
    CTC_PKT_FLAG_NH_OFFSET_IS_8W    = 0x0080,  /**< [GB.GG] [TX] Indicate field nh_offset is 8W, otherwise is 4W */
    CTC_PKT_FLAG_HASH_VALID         = 0x0100,  /**< [GB.GG] [TX] Use field hash, otherwise generated by SDK */
    CTC_PKT_FLAG_SRC_PORT_VALID     = 0x0200,  /**< [GB.GG] [TX] Use field src_port, otherwise use CTC_LPORT_CPU */
    CTC_PKT_FLAG_PKT_TYPE_VALID     = 0x0400,  /**< [GB.GG] [TX] Use field packet_type, otherwise use CTC_PARSER_PKT_TYPE_ETHERNET */
    CTC_PKT_FLAG_INGRESS_MODE       = 0x0800,  /**< [GB.GG] [TX] Indicate field will do IPE processing though I-LOOP channel */
    CTC_PKT_FLAG_BUFFER_VICTIM_PKT  = 0x1000,   /**< [GG] [RX] Indicate the packet is the victim packet of buffer monitor log*/
    CTC_PKT_FLAG_UNKOWN_MACDA  = 0x2000,   /**< [GG] [RX] Indicate the packet macda is unkonwn*/
    CTC_PKT_FLAG_OAM_USE_FID  = 0x4000,   /**< [GG] [TX] Indicate Oam Using fid lookup*/
    CTC_PKT_FLAG_VRFID_VALID     = 0x8000,  /**< [GG] [RX] Indicate vrfid is valid */
    CTC_PKT_FLAG_METADATA_VALID     = 0x10000  /**< [GG] [RX] Indicate metadata is valid */
};
typedef enum ctc_pkt_flag_e ctc_pkt_flag_t;

/**
 @brief Define packet OAM flags
*/
enum ctc_pkt_oam_flag_e
{
    CTC_PKT_OAM_FLAG_LINK_OAM       = 0x0001,   /**< [GB.GG] [ETH,MPLSTP] Indicate is link-level */
    CTC_PKT_OAM_FLAG_IS_DM          = 0x0002,   /**< [GB.GG] [ETH,MPLSTP] Indicate is DM */
    CTC_PKT_OAM_FLAG_IS_LM          = 0x0004,   /**< [GB.GG] [ETH,MPLSTP] Indicate is LM */
    CTC_PKT_OAM_FLAG_IS_MIP         = 0x0008,   /**< [GB.GG] [ETH] Indicate is MIP */
    CTC_PKT_OAM_FLAG_TX_MIP_TUNNEL  = 0x0010,   /**< [GB.GG] [ETH] Indicate bypass MIP configured port when TX */
    CTC_PKT_OAM_FLAG_IS_UP_MEP      = 0x0020,   /**< [GB.GG] [ETH] Indicate is UP MEP */
    CTC_PKT_OAM_FLAG_HAS_MPLS_GAL   = 0x0040,   /**< [GB.GG] [MPLSTP] Indicate has GAL */
    CTC_PKT_OAM_FLAG_HAS_MPLS_CW    = 0x0080    /**< [GB.GG] [MPLSTP] Indicate has CW */
};
typedef enum ctc_pkt_oam_flag_e ctc_pkt_oam_flag_t;

/**
 @brief Define packet type
*/
enum ctc_pkt_oper_type_s
{
    CTC_PKT_OPER_NORMAL = 0,    /**< [GB.GG] Normal Packet */
    CTC_PKT_OPER_C2C    = 4,    /**< [GB.GG] C2C for stacking */
    CTC_PKT_OPER_PTP    = 5,    /**< [GB.GG]PTP Packet */
    CTC_PKT_OPER_OAM    = 7     /**< [GB.GG] OAM Packet */
};
typedef enum ctc_pkt_oper_type_s ctc_pkt_oper_type_t;

/**
 @brief Define OAM type
*/
enum ctc_oam_type_e
{
    CTC_OAM_TYPE_NONE           = 0,    /**< [GB.GG] Invalid Type */
    CTC_OAM_TYPE_ETH            = 1,    /**< [GB.GG] Ethernet OAM */
    CTC_OAM_TYPE_IP_BFD         = 2,    /**< [GB.GG] IP BFD OAM */
    CTC_OAM_TYPE_MPLS           = 6,    /**< [GB.GG] MPLS OAM */
    CTC_OAM_TYPE_MPLS_BFD       = 7,    /**< [GB.GG] MPLS BFD OAM */
    CTC_OAM_TYPE_ACH            = 8,    /**< [GB.GG] MPLSTP OAM */
    CTC_OAM_TYPE_TRILL_BFD      = 10,   /**< [GB.GG] TRILL BFD OAM */
    CTC_OAM_TYPE_TRILL_BFD_ECHO = 11    /**< [GB.GG] TRILL BFD Echo OAM */
};
typedef enum ctc_oam_type_e ctc_oam_type_t;


/**
  @brief Define forwarded packet to cpu module id
*/
enum ctc_cpu_pkttocpu_mod_e
{
    CTC_CPU_PKTTOCPU_MOD_NORMAL_EXCP = 0,  /**< [HB] normal exception */
    CTC_CPU_PKTTOCPU_MOD_FATAL_EXCP,       /**< [HB] fatal exception */
    CTC_CPU_PKTTOCPU_MOD_OAM_EXCP,         /**< [HB] oam exception */
    CTC_CPU_PKTTOCPU_MOD_NORMAL_FWD_CPU,   /**< [HB] normal forward to cpu*/
    CTC_CPU_PKTTOCPU_MOD_ELOOP_FWD_CPU,    /**< [HB] do eloop and forward to cpu*/
    CTC_CPU_PKTTOCPU_MOD_RSV1,             /**< [HB] reserved for future*/
    CTC_CPU_PKTTOCPU_MOD_RSV2,             /**< [HB] reserved for future*/
    CTC_CPU_PKTTOCPU_MOD_RSV3,             /**< [HB] reserved for future*/
    MAX_YS_CPU_PKTTOCPU_MOD_FLAG
};
typedef enum ctc_cpu_pkttocpu_mod_e ctc_cpu_pkttocpu_mod_t;

/*
  define forwarded packet to cpu nexthopptr
   combine:
        |3bit    |      6bit    |        6bit      | 3bit   |   = 18 bit
        [modid][exception index][exception sub index|[cpu mac]
 In humber:
        |3bit    |      6bit    |      5bit  |       4 bit     |    = 18 bit
        [modid][exception index][ Reserved][exception sub index/cpu mac]
       1) if cpu destination  is single cpu , the low 4 bits indicate exception sub index;
       2) if cpu destination  is multiple cpu ,the low 3 bits indicate cpu mac index;
 In Greatbelt/GoldenGate
       |   6bit     | 8bit     |       4 bit     |    = 18 bit
       [    Rsv    ][reason-id     ][     cpu mac    ]
        1) the low 4 bits indicate cpu mac index
       2) the mid 8 bits indicate cpu reason
*/

#define CTC_CPU_PKTTOCPU_BUILDUP_NHPTR(modid, exp_idx, low_9bits)  ((modid) << 15 | (exp_idx) << 9 | (low_9bits))  /**< [HB] Build nexthop_ptr */

#define CTC_PKT_CPU_REASON_BUILD_NHPTR(reason, cpu_mac)  ((reason) << 4 | (cpu_mac & 0xF))  /**< [GB.GG] Build nexthop_ptr by reason and cpu mac index */

#define CTC_PKT_CPU_REASON_GET_BY_NHPTR(nexthop_ptr)     ((nexthop_ptr >> 4) & 0x3FF)       /**< [GB.GG] Get cpu reason by nexthop_ptr */


#define CTC_PKT_CPU_REASON_L2_PDU_RESV  32  /* [GB] max l2 pdu action index is 32 */
#define CTC_PKT_CPU_REASON_L3_PDU_RESV  32  /* [GB] max l3 pdu action index is 32 */
#define CTC_PKT_CPU_REASON_OAM_PDU_RESV 32  /* [GB] max oam pdu action index is 32 */

/*
 @brief Define packet cpu reason
*/
enum ctc_pkt_cpu_reason_e
{
    CTC_PKT_CPU_REASON_DROP        = 0,     /**< [HB.GB.GG] Drop packet */

    /*refert to ctc_l2pdu_action_index_t, ActionIndex is used to map Resson = (CTC_PKT_CPU_REASON_L2_PDU + ActionIndex)*/
    CTC_PKT_CPU_REASON_L2_PDU         = 1,  /**< [GB.GG] L2 pdu start, */

    /*refert to pdu module, refert to ctc_l3pdu_action_index_t, ActionIndex is used to map Resson = (CTC_PKT_CPU_REASON_L3_PDU + ActionIndex)*/
    CTC_PKT_CPU_REASON_L3_PDU         = CTC_PKT_CPU_REASON_L2_PDU + CTC_PKT_CPU_REASON_L2_PDU_RESV, /**<  [GB.GG] L3 pdu start*/

    CTC_PKT_CPU_REASON_IGMP_SNOOPING  = CTC_PKT_CPU_REASON_L3_PDU + CTC_PKT_CPU_REASON_L3_PDU_RESV, /**<  [GB.GG] IGMP-Snooping*/
    CTC_PKT_CPU_REASON_PTP,                 /**< [GB.GG] PTP */
    CTC_PKT_CPU_REASON_MPLS_OAM,            /**< [GB.GG] TMPLS or MPLS protocol OAM */
    CTC_PKT_CPU_REASON_DCN,                 /**< [GB.GG] DCN */
    CTC_PKT_CPU_REASON_SCL_MATCH,           /**< [GB.GG] SCL entry match */
    CTC_PKT_CPU_REASON_ACL_MATCH,           /**< [GB.GG] ACL entry match */
    CTC_PKT_CPU_REASON_SFLOW_SOURCE,        /**< [GB.GG] SFlow source */
    CTC_PKT_CPU_REASON_SFLOW_DEST,          /**< [GB.GG] SFlow destination */

    CTC_PKT_CPU_REASON_L2_PORT_LEARN_LIMIT,  /**< [GB.GG] MAC learn limit base on port */
    CTC_PKT_CPU_REASON_L2_VLAN_LEARN_LIMIT,  /**< [GB.GG] MAC learn limit base on vlan/vsi */
    CTC_PKT_CPU_REASON_L2_SYSTEM_LEARN_LIMIT,/**< [GB.GG] MAC learn limit base on system */
    CTC_PKT_CPU_REASON_L2_MOVE,             /**< [GB.GG] MAC SA station move */
    CTC_PKT_CPU_REASON_L2_CPU_LEARN,        /**< [GB.GG] MAC SA CPU learning */
    CTC_PKT_CPU_REASON_L2_COPY_CPU,         /**< [GB.GG] MAC DA copy to CPU */
    CTC_PKT_CPU_REASON_IP_TTL_CHECK_FAIL,   /**< [GB.GG] IP TTL check fail */
    CTC_PKT_CPU_REASON_L3_MTU_FAIL,         /**< [GB.GG] IP MTU check fail */
    CTC_PKT_CPU_REASON_L3_MC_RPF_FAIL,      /**< [GB.GG] IP multicast RPF check fail */
    CTC_PKT_CPU_REASON_L3_MC_MORE_RPF,      /**< [GB] IP multicast more RPF */
    CTC_PKT_CPU_REASON_TUNNEL_MORE_RPF = CTC_PKT_CPU_REASON_L3_MC_MORE_RPF, /**< [GG] L3 tunnel more RPF */
    CTC_PKT_CPU_REASON_L3_IP_OPTION,        /**< [GB.GG] IP option */
    CTC_PKT_CPU_REASON_L3_ICMP_REDIRECT,    /**< [GB.GG] IP ICMP redirect */
    CTC_PKT_CPU_REASON_L3_COPY_CPU,         /**< [GB.GG] IP DA copy to CPU */

    CTC_PKT_CPU_REASON_L3_MARTIAN_ADDR,     /**< [GB.GG] IP martian address */
    CTC_PKT_CPU_REASON_L3_URPF_FAIL,        /**< [GB.GG] IP URPF fail */
    CTC_PKT_CPU_REASON_IPMC_TTL_CHECK_FAIL, /**< [GB.GG] IP multicast ttl check fail */
    CTC_PKT_CPU_REASON_MPLS_TTL_CHECK_FAIL, /**< [GB.GG] MPLS ttl check fail */
    CTC_PKT_CPU_REASON_GRE_UNKNOWN,         /**< [GB.GG] GRE unknown */
    CTC_PKT_CPU_REASON_LABEL_MISS,          /**< [GB.GG] MPLS label out of range */
    CTC_PKT_CPU_REASON_LINK_ID_FAIL,        /**< [GB.GG] IP Link id check fail */
    CTC_PKT_CPU_REASON_OAM_HASH_CONFLICT,   /**< [GB.GG] OAM hash conflict */
    CTC_PKT_CPU_REASON_IPFIX_HASHCONFLIC,     /**< [GG] IP Fix conflict*/
    CTC_PKT_CPU_REASON_VXLAN_NVGRE_CHK_FAIL,   /**< [GG] Vxlan or NvGre check fail */

    CTC_PKT_CPU_REASON_OAM,                   /**< [GB.GG] OAM PDU from oam engine, refer to ctc_oam_exceptions_t, ExcpIndex is used to map Reason (CTC_PKT_CPU_REASON_OAM + ExcpIndex) */
    CTC_PKT_CPU_REASON_OAM_DEFECT_MESSAGE = CTC_PKT_CPU_REASON_OAM + CTC_PKT_CPU_REASON_OAM_PDU_RESV,  /**< [GB.GG] OAM Defect message from oam engine */

    CTC_PKT_CPU_REASON_FWD_CPU ,              /**< [GB.GG] packet redirect forward to CPU */
    CTC_PKT_CPU_REASON_NEW_ELEPHANT_FLOW,     /**< [GG] New elephant flow */
    CTC_PKT_CPU_REASON_L2_STORM_CTL,          /**< [GB.GG] Storm control*/
    CTC_PKT_CPU_REASON_MONITOR_BUFFER_LOG,    /**< [GG]  Monitor Buffer log*/
    CTC_PKT_CPU_REASON_MONITOR_LATENCY_LOG,   /**< [GG]  Monitor Latency log*/
    CTC_PKT_CPU_REASON_POSTCARD,              /**< [GG] Post card*/
    CTC_PKT_CPU_REASON_QUEUE_DROP_PKT,        /**< [GG] Mobitor Queue Drop packet to cpu*/
    CTC_PKT_CPU_REASON_GENEVE_PKT,            /**< [GG] Geneve packet*/
    CTC_PKT_CPU_REASON_MIRRORED_TO_CPU,       /**< [GB.GG] Mirrored packet to cpu*/
    CTC_PKT_CPU_REASON_L2_VSI_LEARN_LIMIT,    /**< [GB] MAC learn limit base on VSI */

    CTC_PKT_CPU_REASON_ARP_MISS,              /**< [GB.GG] ARP lookup miss */

    /* ----- User define CPU Reason ---- */
    CTC_PKT_CPU_REASON_CUSTOM_BASE = 256,
    CTC_PKT_CPU_REASON_MAX_COUNT = 1024
};
typedef enum ctc_pkt_cpu_reason_e ctc_pkt_cpu_reason_t;

/**
 @brief Define CPU reason destination
*/
enum ctc_pkt_cpu_reason_dest_e
{
    CTC_PKT_CPU_REASON_TO_LOCAL_CPU = 0, /**< [GB.GG] cpu reason to local CPU by DMA */
    CTC_PKT_CPU_REASON_TO_LOCAL_PORT,    /**< [GB.GG] cpu reason to local/remote port */
    CTC_PKT_CPU_REASON_TO_REMOTE_CPU,    /**< [GB.GG] cpu reason to remote cpu */
    CTC_PKT_CPU_REASON_TO_DROP,           /**< [GB.GG] cpu reason to drop */
    CTC_PKT_CPU_REASON_TO_NHID,         /**< [GB.GG] get destination by nexthop*/
    CTC_PKT_CPU_REASON_TO_LOCAL_CPU_ETH, /**< [GB.GG] cpu reason to local CPU by network port */

	CTC_PKT_CPU_REASON_TO_MAX_COUNT

};
typedef enum ctc_pkt_cpu_reason_dest_e ctc_pkt_cpu_reason_dest_t;

/**
 @brief Define CPU reason destination
*/
enum ctc_pkt_cpu_reason_group_type_e
{
    CTC_PKT_CPU_REASON_GROUP_EXCEPTION = 0,  /**< [GB] qos group for packet exception to cpu */
    CTC_PKT_CPU_REASON_GROUP_OAM,            /**< [GB] qos group for packet from OAM engine to cpu */
    CTC_PKT_CPU_REASON_GROUP_FORWARD,        /**< [GB] qos group for packet forward to cpu */
    CTC_PKT_CPU_REASON_GROUP_REMOTE_FORWARD  /**< [GB] qos group for packet from remote chip forward to cpu */
};
typedef enum ctc_pkt_cpu_reason_group_type_e ctc_pkt_cpu_reason_group_type_t;

/**
 @brief Define packet buffer for RX
*/
struct ctc_pkt_buf_s
{
    uint8* data;                /**< [GB.GG] pointer to packet data */
    uint32 len;                 /**< [GB.GG] length of data in bytes */
};
typedef struct ctc_pkt_buf_s ctc_pkt_buf_t;

/**
 @brief Define packet buffer for TX
*/
struct ctc_pkt_skb_s
{
    uint8* head;                /**< [GB.GG] head pointer of the total buffer */
    uint8* data;                /**< [GB.GG] head pointer of the data */
    uint8* tail;                /**< [GB.GG] end pointer of the data */
    uint8* end;                 /**< [GB.GG] end pointer of the total buffer */
    uint32 len;                 /**< [GB.GG] Packet length in bytes */
    uint8  buf[CTC_PKT_MTU];    /**< [GB.GG] Buffer for packet */
};
typedef struct ctc_pkt_skb_s ctc_pkt_skb_t;

/**
 @brief Init packet skb with default length

 @param[in/out] skb     Pointer to packet buffer

 @remark

 @return CTC_E_XXX
*/
static INLINE int32
ctc_packet_skb_init(ctc_pkt_skb_t* skb)
{
    skb->head = skb->buf;
    skb->end = skb->buf + CTC_PKT_MTU;
    skb->data = skb->buf + CTC_PKT_HDR_ROOM;
    skb->tail = skb->data;
    skb->len = 0;
    return 0;
}

/**
 @brief Init packet skb with length of header room

 @param[in/out] skb     Pointer to packet buffer

 @param[in] skb         Length of header room

 @remark

 @return CTC_E_XXX
*/
static INLINE int32
ctc_packet_skb_init_with_len(ctc_pkt_skb_t* skb, uint32 len)
{
    skb->head = skb->buf;
    skb->end = skb->buf + CTC_PKT_MTU;
    skb->data = skb->buf + len;
    skb->tail = skb->data;
    skb->len = 0;
    return 0;
}

/**
 @brief Push packet skb, expand room forwards

 @param[in/out] skb     Pointer to packet buffer

 @param[in]     len     Pushed length

 @remark

 @return CTC_E_XXX
*/
static INLINE uint8*
ctc_packet_skb_push(ctc_pkt_skb_t* skb, uint32 len)
{
    skb->data -= len;
    skb->len += len;
    return skb->data;
}

/**
 @brief Pull packet skb, strip room has processed or need ignored

 @param[in/out] skb     Pointer to packet buffer

 @param[in]     len     Pulled length

 @remark

 @return CTC_E_XXX
*/
static INLINE uint8*
ctc_packet_skb_pull(ctc_pkt_skb_t* skb, uint32 len)
{
    skb->data += len;
    skb->len -= len;
    return skb->data;
}

/**
 @brief Put packet skb, expand room backwards

 @param[in/out] skb     Pointer to packet buffer

 @param[in]     len     Puted length

 @remark

 @return CTC_E_XXX
*/
static INLINE uint8*
ctc_packet_skb_put(ctc_pkt_skb_t* skb, uint32 len)
{
    uint8* tmp = skb->tail;

    skb->tail += len;
    skb->len += len;
    return tmp;
}

/**
 @brief Define timestamp format in packet TX/RX information, used by DM and PTP
*/
struct ctc_packet_ts_s
{
    uint32  seconds;            /**< [GB] seconds */
    uint32  nanoseconds;        /**< [GB] nano seconds */
};
typedef struct ctc_packet_ts_s ctc_packet_ts_t;

/**
 @brief Define packet OAM data-structure
*/
struct ctc_pkt_oam_info_s
{
    uint32  type;               /**< [GB.GG] [RX,TX] OAM type, refer to ctc_oam_type_t */
    uint32  flags;              /**< [GB.GG]  [RX,TX] OAM flags, refer to ctc_pkt_oam_flag_t */
    uint32  dm_ts_offset;       /**< [GB.GG] [TX] [DM] Offset in bytes of timestamp */
    uint16  vid;                /**< [GB.GG] [TX] VLAN ID, valid for UP MEP */
    uint16  mep_index;          /**< [GB.GG] [RX] index of table MEP/RMEP */
    ctc_packet_ts_t dm_ts;      /**< [GB.GG] [RX] [DM] timestamp */
    uint32  lm_fcl;             /**< [GB.GG] [RX] [LM] RxFCl value at the time LMR frame was received */
};
typedef struct ctc_pkt_oam_info_s ctc_pkt_oam_info_t;

/**
 @brief Define PTP opertation type in packet header
*/
enum ctc_ptp_oper_type_e
{
    CTC_PTP_CAPTURE_ONLY,       /**< [GB] Get timestamp and store in TX Capture FIFO */
    CTC_PTP_REPLACE_ONLY,       /**< [GB] Get timestamp and replace into packet */
    CTC_PTP_NULL_OPERATION,     /**< [GB] Do not take any operation */
    CTC_PTP_CORRECTION          /**< [GB] Get timestamp and calculate correction field value into packet */
};
typedef enum ctc_ptp_oper_type_e ctc_ptp_oper_type_t;

/**
 @brief Define packet PTP data-structure
*/
struct ctc_pkt_ptp_info_s
{
    ctc_packet_ts_t     ts;         /**< [GB.GG] [RX,TX] PTP timestamp */
    ctc_ptp_oper_type_t oper;       /**< [GB.GG] [TX] PTP operation type */
    uint8               seq_id;     /**< [GB.GG] [TX] PTP capture sequence Id, only for oper equal to CAPTURE_ONLY */
    uint8               ts_offset;  /**< [GG]  [TX] PTP timestamp offset */
    uint8               resv0[2];   /**< [GB.GG] Reserved for alignment */
};
typedef struct ctc_pkt_ptp_info_s ctc_pkt_ptp_info_t;

/**
 @brief Define packet TX/RX information
*/
struct ctc_pkt_info_s
{
    uint32  flags;               /**< [GB.GG] [RX,TX] flags of the packet, refer to ctc_pkt_flag_t */
    uint32  dest_gport;          /**< [GB.GG] [TX] destination global port ID for unicast, include LinkAgg, valid if CTC_PKT_FLAG_MCAST is not set */
    uint16  dest_group_id;       /**< [GB.GG] [TX] destination group ID for multicast, valid if CTC_PKT_FLAG_MCAST is set */
    uint16  src_svid;            /**< [GB.GG] [RX,TX] source S-VLAN ID */
    uint16  src_cvid;            /**< [GB.GG] [RX,TX] source C-VLAN ID */
    uint32  src_port;            /**< [GB.GG] [RX,TX] source port, valid for TX if CTC_PKT_FLAG_SRC_PORT_VALID is set, or stackingTrunkPort */
    uint8   oper_type;           /**< [GB.GG] [RX,TX] operation type, refer to ctc_pkt_oper_type_t */
    uint8   priority;            /**< [GB.GG] [RX,TX] priority of the packet, range is [0, 63] */
    uint8   color;               /**< [GB.GG] [RX,TX] color of the packet, refer to ctc_qos_color_t */
    uint8   src_cos;             /**< [GB.GG] [RX,TX] COS of the packet, range is [0, 7] */
    uint8   ttl;                 /**< [GB[GG]] [RX,TX] TTL of the packet */
    uint8   is_critical;         /**< [GB.GG] [RX,TX] If set, indicate that the packet should not be droped in queue */
    ctc_pkt_oam_info_t oam;      /**< [GB.GG] [RX,TX] store OAM information, valid if oper_type is CTC_PKT_OPER_OAM */
    ctc_pkt_ptp_info_t ptp;      /**< [GB.GG] [RX,TX] store PTP information, valid if oper_type is CTC_PKT_OPER_PTP */
    uint32  nh_offset;           /**< [GB.GG] [TX] nexthop offset, valid if CTC_PKT_FLAG_NH_OFFSET_VALID flags is set */
    uint8   hash;                /**< [GB.GG] [TX] hash of LAG for load balance, valid if CTC_PKT_FLAG_HASH_VALID flags is set */
    uint8   payload_offset;      /**< [GB.GG] [RX] offset into the packet for start of payload */
    uint8   vlan_domain;    /**< [GG] [TX] refer to ctc_port_vlan_domain_type_t */
    uint8   resv0;               /**< [GB.GG] Reserved for alignment */
    ctc_pkt_cpu_reason_t reason; /**< [GB.GG] [RX] packet to CPU reason */
    uint16  vrfid;               /**< [GB.GG] [RX] VRFID */
    uint8   packet_type;         /**< [GB.GG] [RX] packet type, refer to ctc_parser_pkt_type_t */
    uint8   src_chip;            /**< [GB.GG] [RX] source chip ID */
    uint16 fid;                    /**< [GG] [RX,TX] Forwarding Id */
    uint16 logic_src_port;   /**<[GB.GG] [RX] logic source port*/
    uint16 meta_data;       /**<[GG] [RX] meta data*/

};
typedef struct ctc_pkt_info_s ctc_pkt_info_t;

/**
 @brief Define packet TX data-structure
*/
struct ctc_pkt_tx_s
{
    ctc_pkt_mode_t  mode;       /**< [GB.GG] Packet Transport mode */
    ctc_pkt_skb_t   skb;        /**< [GB.GG] Packet TX buffer */
    ctc_pkt_info_t  tx_info;    /**< [GB.GG] Packet TX information needed to encoded into packet header */
    uint8           lchip;      /**< [GB.GG] Local chip ID the packet expected transmit to */
};
typedef struct ctc_pkt_tx_s ctc_pkt_tx_t;

#define CTC_PKT_TOTAL_HDR_LEN(pkt_rx) \
    ((pkt_rx)->eth_hdr_len + (pkt_rx)->pkt_hdr_len) + (pkt_rx)->stk_hdr_len

/**
 @brief Define packet RX data-structure
*/
struct ctc_pkt_rx_s
{
    ctc_pkt_mode_t  mode;        /**< [GB.GG] Packet Transport mode */
    uint16          pkt_len;     /**< [GB.GG] Packet length in bytes */
    uint8           dma_chan;    /**< [GB.GG] DMA Channel ID of packet RX */
    uint8           eth_hdr_len; /**< [GB.GG] CPUMAC header length in bytes, CTC_PKT_CPUMAC_LEN for ETH, 0 for DMA */
    uint8           pkt_hdr_len; /**< [GB.GG] Packet header length in bytes, CTC_PKT_HEADER_LEN */
    uint8           stk_hdr_len; /**< [GB.GG] Stacking header length in bytes, 0 for packet from local chip */
    uint8           resv0[2];    /**< [GB.GG] Reserved for alignment */
    uint32          buf_count;   /**< [GB.GG] Count of packet buffer array */
    ctc_pkt_buf_t*  pkt_buf;     /**< [GB.GG] Packet buffer array */
    ctc_pkt_info_t  rx_info;     /**< [GB.GG] Packet RX information decoded from packet header */
};
typedef struct ctc_pkt_rx_s ctc_pkt_rx_t;

/**
 @brief Define packet receive callback function prototype
*/
typedef int32 (* CTC_PKT_RX_CALLBACK)(ctc_pkt_rx_t* p_pkt_rx);

/**
 @brief Define packet transmit callback function prototype
*/
typedef int32 (* CTC_PKT_TX_CALLBACK)(ctc_pkt_tx_t* p_pkt_tx);

/**
 @brief Packet global config information
*/
struct ctc_pkt_global_cfg_s
{
    CTC_PKT_RX_CALLBACK     rx_cb;      /**< [GB.GG] Callback function for packet RX */
    CTC_PKT_TX_CALLBACK     socket_tx_cb;      /**< [GB.GG] Callback function for packet TX by Socket*/
    CTC_PKT_TX_CALLBACK     dma_tx_cb;      /**< [GB.GG] Callback function for packet TX by Dma, used for EADP*/
};
typedef struct ctc_pkt_global_cfg_s ctc_pkt_global_cfg_t;

/**@} end of @defgroup packet PACKET  */

#ifdef __cplusplus
}
#endif

#endif

